package com.fingard.dsp.bank.directbank.pos01;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import com.zhongbaofu.util.Util;

public class POS01QryStatement extends POS01Base implements IStatement {

	@Override
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
        retAts.writeStart();

        String[] tmpPosRecRespHeader = null;
        String tmpPosRecTotalNum = "0";
        if ("S".equals(p_reqQrySttm.statementType)) {
            tmpPosRecRespHeader = getPosRecStatement(p_reqQrySttm, retAts);
            tmpPosRecTotalNum = retAts.totalNum;
        }

        String[] tmpGetStatementHeader = getStandardStatement(p_reqQrySttm, retAts);
        String tmpStandardTotalNum = retAts.totalNum;
        if ("".equals(tmpStandardTotalNum)) {
        	tmpStandardTotalNum = "0";
		}
        
        if ("-1".equals(tmpPosRecRespHeader[0]) && "-1".equals(tmpGetStatementHeader[0])) {
			retAts.writeRespCode("-1");
			retAts.writeRespInfo("POS对账单获取失败,原因:" + tmpPosRecRespHeader[1] + ";上海车险对账单获取失败,原因:" + tmpGetStatementHeader[1]);
		} else {
			if (retAts.getWrittenRdCount() == 0) {
				retAts.writeRespCode("0");
				String respInfo = tmpPosRecRespHeader[1];
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = tmpGetStatementHeader[1];
				}
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = "交易为空";
				}
				retAts.writeRespInfo(respInfo);
			}

			retAts.isWritedTotalNum(String.valueOf(Integer.parseInt(tmpPosRecTotalNum) + Integer.parseInt(tmpStandardTotalNum)));
		}

        retAts.writeEnd();
        return retAts;
	}
	
	/**
     * POS对账单
     * 
     * @param p_reqQrySttm
     * @param retAts
     * @return
     * @throws Exception
     */
	private String[] getStandardStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) {
		
		String[] respHeader = new String[]{"", ""};
        
        String tmpRespCode = "";
        String tmpRespInfo = "";
        
        retAts.totalNum = "0";
        int totalNum = 0;
        
        try {
            FtpSet ftpSet = bankFront.getFtpSet("pos");

            ftpSet.downDir = StringHelper.trimEnd(ftpSet.getDownDir("pos"), "/") + "/" + p_reqQrySttm.busDate;

            WriteBankLogLn2("太保付POS对账单FTP服务器地址:" + ftpSet.serverIP + ":" + ftpSet.port);

            StringBuilder sbFileContent = new StringBuilder();
            String downFileName = getBankConfig().getValueAsString("merchantId") + p_reqQrySttm.busDate + ".txt";

            WriteBankLogLn2("太保付POS对账单所在服务器路径:" + ftpSet.downDir + "/" + downFileName);


            String localFilePath = createTempFileDirectory() + File.separator + downFileName;
            WriteBankLogLn2("太保付POS对账单保存本地路径:" + localFilePath);

            FtpReceiver ftpReceiver = null;
			String posRecRequestType = getBankConfig().getValueAsString("posRecRequestType");
			if ("ftp".equals(posRecRequestType.toLowerCase())) {
				FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
	            ftpReceiver = ftpPortClient.downloadFile(downFileName, localFilePath);
			} else if ("sftp".equals(posRecRequestType.toLowerCase())) {
				SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
				String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + downFileName;
				WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
				ftpReceiver = sftpPortClient.downloadFile("", sftpFilePath, localFilePath);
			}
            if (ftpReceiver.isCompleted) {
                if (sbFileContent.length() > 0) {
                    sbFileContent.append("\n");
                }
                sbFileContent.append(FileHelper.readFileText(localFilePath, getCharset("UTF-8", "pos")));
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = "太保付POS对账单下载失败,原因:\r\n" + ftpReceiver.connMsg;
            }

            if (StringHelper.hasAnyChar(sbFileContent.toString())) {
            	tmpRespCode = "0";
            	
                String tmpStrRet = sbFileContent.toString();
                WriteBankLogLn2("太保付POS对账单响应数据:\r\n" + tmpStrRet);

                StringReader strReader = new StringReader(tmpStrRet);
                BufferedReader tmpReader = new BufferedReader(strReader);

                boolean isContinue = false;
                while (true) {
                    String eachline = tmpReader.readLine();
                    if (eachline == null) {
                        break;
                    }
                    if ("".equals(eachline.trim())) {
                        continue;
                    }
                    String[] detailNodes = eachline.split("`~");
                    if (p_reqQrySttm.actNum.equals(detailNodes[1].trim())) {
                        totalNum++;
                        isContinue = true;
                        RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();

                        if (StringHelper.hasAnyChar(detailNodes[4])) {
                            tmpRetDetail.askNumber = detailNodes[4].trim();
                        }

                        tmpRetDetail.cdFlag = "22";

                        if (StringHelper.hasAnyChar(detailNodes[11])) {
                            tmpRetDetail.amount = StringHelper.amountDivide100(detailNodes[11].trim());
                        }

                        if (StringHelper.hasAnyChar(detailNodes[15])) {
                            tmpRetDetail.fee = StringHelper.amountDivide100(detailNodes[15].trim());
                        }

                        tmpRetDetail.busTime = detailNodes[6];

                        if (StringHelper.hasAnyChar(detailNodes[7])) {
                            tmpRetDetail.oppAct = detailNodes[7].trim();
                        }

                        if (StringHelper.hasAnyChar(detailNodes[8])) {
                            tmpRetDetail.oppActName = detailNodes[8].trim();
                        }

                        if ("2".equals(detailNodes[13].trim())) {
                            tmpRetDetail.transState = TransState.Success;
                        } else {
                            tmpRetDetail.transState = TransState.Fail;
                        }

                        retAts.writeRetDetail(tmpRetDetail);
                    }
                }

                if (!isContinue) {
                    tmpRespCode = "0";
                    tmpRespInfo = "没有符合条件的记录!";
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.totalNum = String.valueOf(totalNum);

        respHeader[0] = tmpRespCode;
        respHeader[1] = tmpRespInfo;

        return respHeader;
	}

	private String[] getPosRecStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) {
		String[] respHeader = new String[]{"", ""};

        String respCode = "";
        String respInfo = "";
        retAts.totalNum = "0";
        int totalNum = 0;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "unifiedorder");
            if (actItem != null) {
                String mchId = actItem.merchantId;
                /*签名及计算长度用xml*/
                XmlTextWriter tmpXml = new XmlTextWriter();
                tmpXml.autoFormat = false;
                /*发送银行用xml*/
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                /*头部信息*/
                xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                tmpXml.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                xmlWriter.writeStartElement("MESSAGE");
                tmpXml.writeStartElement("MESSAGE");
                xmlWriter.writeStartElement("MHEAD");
                tmpXml.writeStartElement("MHEAD");
                //接口版本号
                xmlWriter.writeElementString("VERSION", "1.0");
                tmpXml.writeElementString("VERSION", "1.0");
                //产品代码
                xmlWriter.writeElementString("PROCCODE", "P1011");
                tmpXml.writeElementString("PROCCODE", "P1011");
                //商户号
                xmlWriter.writeElementString("MERCHANTID", mchId);
                tmpXml.writeElementString("MERCHANTID", mchId);
                //请求时间yyyyMMddHHmmss
                String transDate = Format.DateTime14Format.format(new Date());
                xmlWriter.writeElementString("PTIME", transDate);
                tmpXml.writeElementString("PTIME", transDate);
                xmlWriter.writeEndElement();
                tmpXml.writeEndElement();
                xmlWriter.writeStartElement("MBODY");
                tmpXml.writeStartElement("MBODY");
                /*账单日期yyyyMMdd*/
                String busDateStr = Format.Date8Format.format(p_reqQrySttm.getBusDate());
                xmlWriter.writeElementString("STATEMENTDATE", busDateStr);
                tmpXml.writeElementString("STATEMENTDATE", busDateStr);
//				/*操作方式编码  01-车险付费平台    02-Pos  03-Weixin				 */
//				xmlWriter.writeElementString("OPERATECODE",busDateStr );
//				tmpXml.writeElementString("OPERATECODE", busDateStr);
//				/*支付渠道编码*/
//				xmlWriter.writeElementString("SERVICECHANNEL",busDateStr );
//				tmpXml.writeElementString("SERVICECHANNEL", busDateStr);

                tmpXml.writeEndDocument();
                WriteBankLogLn("发送银行原始报文\r\n" + tmpXml.toXmlString());
                /*长度计算不包括 MAC 值。长度位数不足左补0*/
                String mac = Util.xorAndGenMac(tmpXml.toXmlString(), actItem.saltKey);
                xmlWriter.writeElementString("MAC", mac);
                xmlWriter.writeEndDocument();
                String lengthStr = Integer.toHexString(tmpXml.toXmlString().length());
                lengthStr = "0000".substring(0, 4 - lengthStr.length()) + lengthStr;
                String tmpStr = lengthStr.toUpperCase() + xmlWriter.toXmlString();
                String[] tmpStrRet = sendToBank(tmpStr, bankFront.getUrl("unifiedUrl"));

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    // 解析银行返回
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        /*验签*/
                        if (verifySignByRSA(tmpStrRet[1], actItem.saltKey)) {
                            String rtncode = tmpBkReader.getFirstText("/MESSAGE/MHEAD/RETCODE");
                            /*OK：成功；ER：失败；BO：中断*/
                            if ("00".equals(rtncode)) {
                                while (tmpBkReader.read("/MESSAGE/MBODY/BILL")) {
                                    RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();
                                    String amount = tmpBkReader.readedXElement.getSingleText("AMT");
                                    tmpRetDetail.amount = StringHelper.amountDivide100(amount);
                                    tmpRetDetail.askNumber = tmpBkReader.readedXElement.getSingleText("BZSN");
                                    tmpRetDetail.busTime = tmpBkReader.readedXElement.getSingleText("PAYTIME");
//                                    tmpRetDetail.oppAct = tmpBkReader.readedXElement.getSingleText("PAYTIME");
//                                    tmpRetDetail.oppActName = tmpBkReader.readedXElement.getSingleText("PAYTIME");
                                    tmpRetDetail.cdFlag = "22";
                                    tmpRetDetail.transState = TransState.Success;
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                String errMsg = tmpBkReader.getFirstText("/MESSAGE/MBODY/ERRMSG");
                                respCode = "-1";
                                respInfo = errMsg;
                            }
                        } else {
                            respCode = "-1";
                            respInfo = "签名验证失败";
                            WriteBankLogLn("签名验证失败:" + actItem.saltKey);
                        }
                    } else {
                        respCode = "-1";
                        respInfo = tmpSbMsg.toString();
                    }

                } else {
                    respCode = "-1";
                    respInfo = tmpStrRet[1];
                }
            } else {
                respCode = "-1";
                respInfo = "未找到账号[" + p_reqQrySttm.actNum + "]商户配置信息";
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            respCode = "-1";
            respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        int total = 0;
        try {
            total = Integer.parseInt(retAts.totalNum);
        } catch (Exception ignored) {
        }
        retAts.totalNum = String.valueOf(total + totalNum);

        respHeader[0] = respCode;
        respHeader[1] = respInfo;

        return respHeader;
	}

}
